package com.tron.dobest.java.tronthread;

import java.util.Random;
import java.util.concurrent.Semaphore;

public class UserSemaphoreThread extends Thread{
    private final BoundedResource boundedResource;

    public UserSemaphoreThread(BoundedResource boundedResource) {
        this.boundedResource = boundedResource;
    }

    public static void main(String[] args) {
        BoundedResource boundedResource = new BoundedResource(3);
        for (int i = 0; i < 10; i++) {
            new UserSemaphoreThread(boundedResource).start();
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                boundedResource.use();
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static class BoundedResource{
        private final Semaphore semaphore;
        private final int permits;
        private final Random random = new Random(31415);

        public BoundedResource(int permits) {
            this.semaphore = new Semaphore(permits);
            this.permits = permits;
        }

        public void use() throws InterruptedException {
            semaphore.acquire();
            try {
                doUse();
            } finally {
                semaphore.release();
            }

        }

        protected void doUse() throws InterruptedException {
            System.out.println("BEGIN: used = " + (permits - semaphore.availablePermits()));
            Thread.sleep(random.nextInt(500));
            System.out.println("END: used = " + (permits - semaphore.availablePermits()));
        }
    }
}
